#include <bits/stdc++.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/mman.h>

using namespace std;

string testFile = "/data/test_data.txt";
string resultFile = "/projects/student/result.txt";

int node_num = 0;
uint inputs[2*2000000];
uint nodes[2*2000000];
int G[2000000][60];
int RG[2000000][60];
int len[2000000]={0};
int rlen[2000000]={0};
unordered_map<int, uint> trans[2000000];
int ans3[10000000][3], p3=0;
int ans4[10000000][4], p4=0;
int ans5[10000000][5], p5=0;
int ans6[20000000][6], p6=0;
int ans7[20000000][7], p7=0;
char buf[77*20000000];
bool vis[2000000];
int avl[2000000];
int p[7];

uint parse_1(char** s){
	char *p = *s;
	uint val = *(p++) - '0';
	while(*p != ',') val = 10*val + *(p++) - '0';
	*s = p+1;
	return val;
}
uint parse_2(char** s){
	char *p = *s;
	uint val = *(p++) - '0';
	while(*p != '\r' && *p != '\n') val = 10*val + *(p++) - '0';
	*s = *p=='\r' ? p+2:p+1;
	return val;
}

void loadData_and_createGrap(){
	int fd = open(testFile.c_str(), O_RDONLY);
    int size = lseek(fd, 0, SEEK_END);
    char* p_map =(char*)mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0);
    close(fd);
	char *p = p_map;
	int m=0, n=0;
	uint money[2000000];
	while(*p != '\0'){
		inputs[n++]=parse_1(&p);
		inputs[n++]=parse_1(&p);
		money[m++]=parse_2(&p);
	}
	memcpy(nodes, inputs, 4*n);
	sort(nodes, nodes+n);
	node_num = unique(nodes, nodes+n) - nodes;
	unordered_map<uint, int> idHash;
	for(int i=0; i<node_num; i++) idHash[nodes[i]]=i;
	for(int i=0,a=0,b=0, m=0; i<n; i+=2){
		a=idHash[inputs[i+0]];
		b=idHash[inputs[i+1]];
		if(a==b){m++;continue;}
		G[a][len[a]++]=b;
		RG[b][rlen[b]++]=a;
		trans[a][b]=money[m++];
	}
	for(int i=0; i<node_num; i++) sort(G[i],G[i]+len[i]);
	munmap(p_map, size);
}

char node_chars[2000000][12];
short length[2000000];
void parse_to_char(uint a, char *tmp, int &k){
	int n=0;
	do{tmp[n++] = a%10+'0';}while((a/=10)>0);
	reverse(tmp, tmp+n);
	tmp[n++]=',';
	length[k]=n;
}
void save(){
	int n=sprintf(buf,"%d\n",p3+p4+p5+p6+p7);
	int i, j, v;
	for(i=0; i<node_num; i++) parse_to_char(nodes[i], node_chars[i], i);
	for(i=0; i<p3; i++){
		for(j=0; j<3; j++){
			v=ans3[i][j];
			memcpy(buf+n, node_chars[v], length[v]);
			n+=length[v];
		}
		buf[n-1]='\n';
	}
	for(i=0; i<p4; i++){
		for(j=0; j<4; j++){
			v = ans4[i][j];
			memcpy(buf+n, node_chars[v], length[v]);
			n+=length[v];
		}
		buf[n-1]='\n';
	}
	for(i=0; i<p5; i++){
		for(j=0; j<5; j++){
			v = ans5[i][j];
			memcpy(buf+n, node_chars[v], length[v]);
			n+=length[v];
		}
		buf[n-1]='\n';
	}
	for(i=0; i<p6; i++){
		for(j=0; j<6; j++){
			v = ans6[i][j];
			memcpy(buf+n, node_chars[v], length[v]);
			n+=length[v];
		}
		buf[n-1]='\n';
	}
	for(i=0; i<p7; i++){
		for(j=0; j<7; j++){
			v = ans7[i][j];
			memcpy(buf+n, node_chars[v], length[v]);
			n+=length[v];
		}
		buf[n-1]='\n';
	}
	int fd = open(resultFile.c_str(), O_RDWR|O_CREAT, 0666);
	lseek(fd, n-1, SEEK_SET);
	write(fd, "", 1);
	char* p_map =(char*)mmap(NULL, n, PROT_WRITE, MAP_SHARED, fd, 0);
	memcpy(p_map, buf, n);
	munmap(p_map, n);
	close(fd);
}

inline bool check(const uint &x, const uint &y){
	return x<=5ll*y && y<=3ll*x;
}

void dfs(int &head, int &last, int &cur, int dep){
	uint money = dep > 1 ? trans[last][cur]:0;
	p[dep-1]=cur;
	for(int i=0,v=G[cur][0]; i<len[cur]; v=G[cur][++i]){
		if(dep>1 && !check(money, trans[cur][v])) continue;
		if(v==head && dep>2){
			if(check(trans[cur][v], trans[v][p[1]])){
				switch(dep){
					case 3:
						memcpy(ans3[p3++], p, 12);
						break;
					case 4:
						memcpy(ans4[p4++], p, 16);
						break;
					case 5:
						memcpy(ans5[p5++], p, 20);
						break;
					case 6:
						memcpy(ans6[p6++], p, 24);
						break;
				}
			}
			continue;
		}
		if(dep==6 || avl[v]!=head || vis[v]) continue;
		vis[cur] = true;
		dfs(head, cur, v, dep+1);
		vis[cur] = false;
	}
}

void dfs1(int &head, int &cur, int dep){
	int length = len[cur], i=0;
	for(int v=G[cur][0]; i<length; v=G[cur][++i]){
		if(v < head || vis[v]) continue;
		avl[v] = head;
		if(dep == 2) continue;
		vis[cur] = true;
		dfs1(head, v, dep+1);
		vis[cur] = false;
	}
}

void dfs2(int &head, int &cur, int dep){
	int length = rlen[cur], i=0;
	for(int v=RG[cur][0]; i<length; v=RG[cur][++i]){
		if(v < head || vis[v]) continue;
		avl[v] = head;
		if(dep == 3) continue;
		vis[cur] = true;
		dfs2(head, v, dep+1);
		vis[cur] = false;
	}
}

void loop(int &u){
	p[0]=u;
	for(int i=0,v1=G[u][0]; i<len[u]; v1=G[u][++i]){
		if(avl[v1]!=u) continue;
		for(int j=0,v2=G[v1][0]; j<len[v1]; v2=G[v1][++j]){
			if(avl[v2]!=u || !check(trans[u][v1], trans[v1][v2])) continue;
			for(int k=0,v3=G[v2][0]; k<len[v2]; v3=G[v2][++k]){
				if(v3<u || v3==v1 || v3==u || !check(trans[v1][v2], trans[v2][v3])) continue;
				for(int m=0,v4=G[v3][0]; m<len[v3]; v4=G[v3][++m]){
					if(avl[v4]!=u || v4==v2 || v4==v1 || !check(trans[v2][v3], trans[v3][v4])) continue;
					for(int n=0,v5=G[v4][0]; n<len[v4]; v5=G[v4][++n]){
						if(avl[v5]!=u || v5==v3 || v5==v2 || v5==v1  || !check(trans[v3][v4], trans[v4][v5])) continue;
						for(int q=0,v6=G[v5][0]; q<len[v5]; v6=G[v5][++q]){
							if(avl[v6]!=u) continue;
							if(v6==v1 || v6==v2 || v6==v3 || v6==v4 || !check(trans[v4][v5], trans[v5][v6])) continue;
							if(find(G[v6],G[v6]+len[v6], u)==G[v6]+len[v6] || !check(trans[v5][v6], trans[v6][u])) continue;
							if(!check(trans[v6][u], trans[u][v1])) continue;
							p[1]=v1;
							p[2]=v2;
							p[3]=v3;
							p[4]=v4;
							p[5]=v5;
							p[6]=v6;
							memcpy(ans7[p7++], p, 28);
						}
					}
				}
			}
		}
	}
}

void solve(){
	memset(vis, 0, sizeof(vis));
	memset(avl, -1, sizeof(avl));
	for(int i=0;i<node_num;i++){
		if(len[i]!=0 && rlen[i]!=0){
			dfs1(i,i,1);
			dfs2(i,i,1);
			dfs(i,i,i,1);
			loop(i);
		}
	}
}

int main(int argc, char* argv[]){
	loadData_and_createGrap();
	solve();
	save();
	exit(0);
}